package io.itit.ecp.data;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.itit.ecp.admin.server.entity.EmissionReductionFactorEntity;
import io.itit.ecp.admin.server.service.IEmissionReductionFactorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 减排因子数据生成
 */
@Slf4j
@Component
public class EmissionReductionFactorGenerate {

    @Resource
    private IEmissionReductionFactorService emissionReductionFactorService;

    /**
     * 每月1号凌晨执行任务，生成上个月的 减排因子数据
     */
    @Scheduled(cron = "0 0 0 1 * ?")
    public void generate() {
        LocalDateTime start = LocalDate.now().minusMonths(1).with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay();
        LocalDateTime end = LocalDate.now().minusMonths(1).with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX);
        log.info("generate EmissionReductionFactor start...");
        List<EmissionReductionFactorEntity> list = emissionReductionFactorService.lambdaQuery()
                .ge(EmissionReductionFactorEntity::getSolidifyDate, start)
                .lt(EmissionReductionFactorEntity::getSolidifyDate, end)
                .orderByDesc(EmissionReductionFactorEntity::getSolidifyDate)
                .list();
        if (list.isEmpty()) {
            log.warn("Unable to find data from last month, start:{},end:{}", start, end);
            return;
        }
        LocalDateTime thisMonthStart = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(LocalTime.MIN);
        LocalDateTime thisMonthEnd = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX);
        Map<String, List<EmissionReductionFactorEntity>> energyTypeMap = list.stream()
                .collect(Collectors.groupingBy(EmissionReductionFactorEntity::getEnergyTypeId));
        for (Map.Entry<String, List<EmissionReductionFactorEntity>> entry : energyTypeMap.entrySet()) {
            EmissionReductionFactorEntity lastMonthData = entry.getValue().get(0);
            if (emissionReductionFactorService.count(new LambdaQueryWrapper<EmissionReductionFactorEntity>()
                    .eq(EmissionReductionFactorEntity::getEnergyTypeId, lastMonthData.getEnergyTypeId())
                    .ge(EmissionReductionFactorEntity::getSolidifyDate, thisMonthStart)
                    .lt(EmissionReductionFactorEntity::getSolidifyDate, thisMonthEnd)
            ) == 0L) {
                EmissionReductionFactorEntity emissionReductionFactor = new EmissionReductionFactorEntity();
                emissionReductionFactor.setFactor(lastMonthData.getFactor());
                emissionReductionFactor.setSolidifyDate(new Date());
                emissionReductionFactor.setEnergyTypeId(lastMonthData.getEnergyTypeId());
                emissionReductionFactor.setUnit(lastMonthData.getUnit());
                emissionReductionFactor.setRemark(lastMonthData.getRemark());
                emissionReductionFactorService.save(emissionReductionFactor);
            }
        }
        log.info("generate EmissionReductionFactor end...");
    }
}
